home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: File.c
-
- Contains: This is the FCB dcmd.
-
- Written by: JM3 = Jim Murphy
- DAL = Dave Lyons
- sad = Scott Douglas
-
- Copyright: © 1988,1993-1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <11> 27-Jan-96 JM3 And the project lead declared, “alpha! beta! final! GM!”
- <10> 25-Jan-96 JM3 Added sample build commands.
- <9> 10/5/95 DAL Made source legible. Options still don't combine, though. Could
- use more work, but it's mo-better than before.
- <8> 10/4/95 DAL Added -t type option. Version 3.0.2d1. Ya know, this command is
- *really* unreadable, thanks in large part to me. It is begging
- to be whaled upon mightily...de-elsed and disentangled. There
- are now enough options that the combinations should work, like
- 'file "Sys" -t MACS', but they don't combine.
- <7> 4/18/95 DAL Omit some boring fields from the "file 0" display (for logs).
- <6> 2/21/95 DAL Made "file 0" show all open files except for fonts (to help
- shrink Standard Logs). Bumped version to 3.0.1.
- <5> 10-Dec-94 JM3 Updated for new format 3 dcmd requirements.
- <4> 5/13/94 DAL Deal with carriage returns inside filenames (changed put.c).
- <3> 24-Jan-94 JM3 With the Universal Interfaces, EqualString is now in
- TextUtils.h. Blah.
- <2> 9/13/93 DAL made some columns wider and fixed the filename-prefix feature to
- work again
-
- Old history:
-
- 29Nov88 sad revised for new dcmd names.
- 5Oct88 sad broke out formatting routines to put.c
- 30Sep88 sad written
-
- The following MPW commands will build the dcmd and copy it to the "Debugger Prefs" file
- in the System folder. The dcmd's name in MacsBug will be the name of the file built by
- the Linker.
-
- C File.c
- Link -o File -sg Main=STDCLIB,STDIO,SANELIB dcmdGlue.a.o File.c.o Put.c.o ∂
- "{Libraries}Runtime.o" "{Libraries}Interface.o"
- BuildDcmd File 194 -format3
- Echo 'include "File";' | Rez -a -o "{SystemFolder}Debugger Prefs"
-
- */
-
- #include <Types.h>
- #include <Memory.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <TextUtils.h>
-
- #include "dcmd.h"
- #include "put.h"
-
-
- //----------------------------------------------------------------------------------------
- // ••• Lomem stuff •••
- //----------------------------------------------------------------------------------------
-
- #define FSFCBLen 0x3f6
- #define FCBsPtr 0x34e
-
-
- typedef struct FCB
- {
- unsigned long fcbFlNum;
- unsigned char fcbMdRByt;
- unsigned char fcbTypByt;
- unsigned short fcbSBlk;
- unsigned long fcbEOF;
- unsigned long fcbPLen;
- unsigned long fcbCrPs;
- VCB* fcbVPtr;
- void* fcbBfAdr;
- unsigned short fcbFlPos;
- unsigned long fcbClmpSize;
- void* fcbBTCBPtr;
- unsigned long fcbExtRec[3];
- OSType fcbFType;
- unsigned long fcbCatPos;
- unsigned long fcbDirID;
- char fcbCName[32];
- }
- FCB;
-
-
- //----------------------------------------------------------------------------------------
- // DrawHeader:
- //----------------------------------------------------------------------------------------
- static void DrawHeader(Boolean shortForm)
- {
- // 1 2 3 4 5 6 7
- // 1234567890123456789012345678901234567890123456789012345678901234567890
-
- if (shortForm)
- dcmdDrawLine("\pfRef File Vol Type Fl Fork LEof");
- else
- dcmdDrawLine("\pfRef File Vol Type Fl Fork LEof Mark FlNum Parent FCB at");
- }
-
-
- //----------------------------------------------------------------------------------------
- // IsFontFile:
- //----------------------------------------------------------------------------------------
- static Boolean IsFontFile(FCB *fcbp)
- {
- OSType filetype = fcbp->fcbFType;
-
- if (filetype == 'FFIL' || filetype == 'ffil' || filetype == 'tfil')
- return true;
-
- return false;
- }
-
-
- //----------------------------------------------------------------------------------------
- // DrawFCB:
- //----------------------------------------------------------------------------------------
- static void DrawFCB(int fref, FCB* fcbp, Boolean shortForm)
- {
- PutUHexWord(fref);
- PutSpace();
- PutPStrTruncTo(fcbp->fcbCName, 17+10);
- PutSpace();
- PutPStrTruncTo(fcbp->fcbVPtr->vcbVN, 26+10+3);
- PutSpace();
- PutOSType(fcbp->fcbFType);
- PutSpace();
- PutChar((fcbp->fcbMdRByt & 0x80) ? 'D' : 'd');
- PutChar((fcbp->fcbMdRByt & 0x01) ? 'W' : 'w');
- PutSpace();
- if (fcbp->fcbMdRByt & 0x02)
- PutPStr("\prsrc ");
- else
- PutPStr("\pdata ");
- PutUDecTo(fcbp->fcbEOF,47+11+3);
-
- if (!shortForm)
- {
- PutSpace();
- PutUDecTo(fcbp->fcbCrPs,55+12+3);
- PutSpace();
- PutUHexZTo(fcbp->fcbFlNum,6,62+12+3);
- PutSpace();
- PutUHexZTo(fcbp->fcbDirID,6,69+12+3);
- PutSpace();
- PutUHexZTo((unsigned long)fcbp,6,76+12+3);
- }
-
- PutLine();
- }
-
-
- //----------------------------------------------------------------------------------------
- // PrefixPStr
- // returns true if astr is equal to a prefix of bstr.
- // (astr must not be longer than 31 characters)
- //----------------------------------------------------------------------------------------
- static Boolean PrefixPStr(const Str255 astr, const Str255 bstr)
- {
- char newstr[31];
- int alen = *astr;
- int blen = *bstr;
-
- if (alen <= blen)
- {
- BlockMoveData(bstr+1, newstr+1, alen);
- newstr[0] = alen;
- return EqualString(astr, newstr, false, true);
- }
-
- return false;
- }
-
-
- //----------------------------------------------------------------------------------------
- // DoHelp:
- //----------------------------------------------------------------------------------------
- static void DoHelp(void)
- {
- dcmdDrawLine("\pDisplays file information on all open files, or for the given fRefNum,");
- dcmdDrawLine("\pfilename, or for all files of the given filetype. Flags are D/d=Dirty,");
- dcmdDrawLine("\pW/w=writeable. \"file 0\" shows all open files except for fonts.");
- }
-
-
-
- //----------------------------------------------------------------------------------------
- // ••• parsed options •••
- //----------------------------------------------------------------------------------------
-
- Boolean gDoOneFCB, gHaveFileName;
- OSType gFiletype;
- long gRefnum;
-
-
- //----------------------------------------------------------------------------------------
- // DoFileCommand:
- //----------------------------------------------------------------------------------------
- void DoFileCommand(dcmdBlock *paramPtr)
- {
- short c;
- int fcbLen; // the length of one fcb
- char* fcbsbase;
- int fcbslen; // the length of the fcbs block
- Str255 filename;
-
- gDoOneFCB = false;
- gHaveFileName = false;
- gFiletype = 0;
-
- dcmdDrawLine("\pDisplaying File Control Blocks");
-
- fcbLen = * (unsigned short *) FSFCBLen;
- fcbsbase = * (char **) FCBsPtr;
- fcbslen = * (unsigned short *) fcbsbase;
-
- if (fcbLen != sizeof(FCB))
- {
- PutPStr("\FSFCBLen = ");
- PutUDec(fcbLen);
- PutPStr("\p expected ");
- PutUDec(fcbLen);
- PutLine(sizeof(FCB));
- return;
- }
-
- if ((fcbslen - 2) % fcbLen != 0)
- {
- PutPStr("\pBad fcbslen ");
- PutUHexWord(fcbslen);
- PutLine();
- return;
- }
-
- c = dcmdPeekAtNextChar();
- if (c == '"' || c == '\'')
- {
- gHaveFileName = true;
- (void) dcmdGetNextParameter(filename); // get the filename ('file "name"')
- }
- else if (c == '-') // look for "-t type"
- {
- dcmdGetNextParameter(filename);
- if (filename[0] != 2 || filename[1] != '-' || filename[2] != 't') // not "-t" ?
- {
- PutPStr("\pBad option");
- PutLine();
- return;
- }
-
- dcmdGetNextParameter(filename); // get the filetype ('file -t type')
- gFiletype = ' ';
- if (filename[0] == 0 || filename[0] > 4)
- {
- PutPStr("\pBad filetype");
- PutLine();
- return;
- }
-
- BlockMoveData(&filename[1], &gFiletype, filename[0]);
- }
- else
- {
- (void) dcmdGetNextExpression(&gRefnum, &gDoOneFCB); // get single file refnum
- }
-
-
- // ••• handle 'file <refnum>' (display info on a single file)
-
- if (gDoOneFCB && gRefnum)
- {
- FCB *fcbp;
-
- gRefnum = (unsigned short) gRefnum;
- if ((gRefnum > fcbslen) || ((gRefnum - 2) % fcbLen != 0))
- {
- PutPStr("\pBad file refnum ");
- PutUHexWord(gRefnum);
- PutLine();
- return;
- }
-
- fcbp = (FCB *) (gRefnum + fcbsbase);
-
- if (fcbp->fcbFlNum)
- {
- DrawHeader(false /* long form */);
- DrawFCB(gRefnum, fcbp, false /* long form */);
- return;
- }
-
- PutPStr("\pFCB ");
- PutUHexWord(gRefnum);
- PutPStr("\p is not in use");
- PutLine();
- return;
- }
-
-
- // ••• handle 'file' and 'file 0' (show all open files, or abbreviated form of all files)
-
- {
- int numFCBs = (fcbslen - 2) / fcbLen;
- int fcbsUsed = 0;
- int numFontsSkipped = 0;
- Boolean foundOne = false;
-
- for (gRefnum = 2; gRefnum < fcbslen; gRefnum += fcbLen)
- {
- FCB* fcbp = (FCB *) (fcbsbase + gRefnum);
-
- if (paramPtr->aborted)
- return;
-
- if (!fcbp->fcbFlNum) // if ______, skip this one
- continue;
-
- if (gHaveFileName && !PrefixPStr(filename, fcbp->fcbCName))
- continue; // skip if it doesn't begin with specified name
-
- if (gFiletype && (gFiletype != fcbp->fcbFType))
- continue;
-
- fcbsUsed++;
-
- if (!foundOne++) // draw header the first time
- DrawHeader(gDoOneFCB); // true = short form ("file 0")
-
- if (gDoOneFCB && IsFontFile(fcbp)) // gDoOneFCB here means there was a refnum (0) on the command line
- numFontsSkipped++;
- else
- DrawFCB(gRefnum, fcbp, gDoOneFCB /* true for short form (for 'file 0') */);
- }
-
-
- // summarize the results
-
- if (gHaveFileName)
- {
- if (!foundOne)
- {
- PutPStr("\pNo open files match \"");
- PutPStr(filename);
- PutChar('"');
- PutLine();
- }
- return;
- }
-
- if (gFiletype != 0) // for now, don't summarize if we filtered by filetype
- return;
-
- PutUDec(numFCBs);
- PutPStr("\p FCBs, ");
- PutUDec(fcbsUsed);
- PutPStr("\p in use");
-
- if (numFontsSkipped)
- {
- PutPStr("\p (including ");
- PutUDec(numFontsSkipped);
- PutPStr("\p fonts not listed)");
- }
- PutPStr("\p, ");
-
- PutUDec(numFCBs - fcbsUsed);
- PutPStr("\p free");
- PutLine();
- }
- }
-
-
- //----------------------------------------------------------------------------------------
- // CommandEntry:
- //----------------------------------------------------------------------------------------
- pascal void CommandEntry(dcmdBlock* paramPtr)
- {
- switch (paramPtr->request)
- {
- case dcmdInit:
- break;
-
- case dcmdHelp:
- DoHelp();
- break;
-
- case dcmdGetInfo:
- {
- static const char usageStr[] = "\p[fRefNum | \"file name\" | -t \"type\"]";
-
- * (long *) &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->dcmdVersion = 0x03028000; // version 3.0.2
- BlockMoveData(&usageStr, &((GetInfoRequestBlockPtr) paramPtr->requestIOBlock)->usageStr, usageStr[0]+1);
- break;
- }
-
- case dcmdDoIt:
- dcmdSwapWorlds();
- DoFileCommand(paramPtr);
- dcmdSwapWorlds();
- break;
-
- // Format 3 and newer dcmds must quietly ignore requests we don't recognize.
-
- default:
- break;
- }
- }
-